package com.example.demo2_review.deadlock_example;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author zwp14
 * @create 2024/6/21 14:50
 * @description 死锁示例
 */
public class DeadlockExample {

    private final Lock lock = new ReentrantLock();

    /*
     * 两个或多个线程被阻塞，它们各自持有对方需要的锁。
     * 由于彼此互相等待对方释放锁，导致它们永远无法继续执行下去，
     * 这种情况被称为死锁。*/
    private static final Object LOCK_1 = new Object();
    private static final Object LOCK_2 = new Object();

    //    private static final ThreadPoolTaskExecutor EXECUTOR = new ThreadPoolTaskExecutor();
    public static void main(String[] args) {
//        EXECUTOR.setThreadNamePrefix("zwp-creat-thread-deadlock-");
//        EXECUTOR.setCorePoolSize(1);
//        EXECUTOR.setMaxPoolSize(1);
//        EXECUTOR.setQueueCapacity(1);
//        EXECUTOR.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//        EXECUTOR.initialize();

//        deadlockTest1();
//        deadlockTest2();

//        EXECUTOR.execute(DeadlockExample::deadlockTest1);
//        EXECUTOR.execute(DeadlockExample::deadlockTest2);
//
//        EXECUTOR.shutdown();

        /*
         * thread1首先获取到lock1，需要再获取到lock2才能执行下去
         * thread2首先获取到lock2，需要再获取到lock1才能执行下去
         * 它们各自持有对方需要的锁，由于彼此互相等待对方释放锁，导致它们永远无法继续执行下去，死锁！*/
        Thread thread1 = new Thread(() -> {
            deadlockTest1();
        }, "zwp_deadlock_test_service");

        Thread thread2 = new Thread(() -> {
            deadlockTest2();
        }, "zwp_deadlock_test_service");

        thread1.start();
        thread2.start();

    }

    private static void deadlockTest2() {
        synchronized (LOCK_2) {
            String name1 = Thread.currentThread().getName();
            System.out.println(name1 + ":deadlockTest2-test-get-！！lock2！！-println");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (LOCK_1) {
                String name2 = Thread.currentThread().getName();
                System.out.println(name2 + ":deadlockTest2-test-get-！！lock1！！-println");
            }
        }
    }

    private static void deadlockTest1() {
        synchronized (LOCK_1) {
            String name1 = Thread.currentThread().getName();
            System.out.println(name1 + ":deadlockTest1-test-get-！！lock1！！-println");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (LOCK_2) {
                String name2 = Thread.currentThread().getName();
                System.out.println(name2 + ":deadlockTest1-test-get-！！lock2！！-println");
            }
        }
    }

}
